<?php
/**
 * @link https://ym2.cleverstone.top
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

use builder\helper\H5;
use yii\helpers\Json;
use builder\helper\Url;
use builder\helper\App;

/* ====== 树表格构建器 ====== */

/** @var \yii\web\View $this */
/* @var string $id 当前树表组件ID */
/* @var string $url 当前树表URL */
/* @var string $treeAsyncOption 异步加载配置项 */
/* @var string $treeCustomNameOption 自定义属性名选项 */
/* @var string $treeViewOption 视图相关的属性集合 */
/* @var string $treeDataOption 数据相关的属性集合 */
/* @var boolean $page 是否分页 */
/* @var string $className 给树表主容器追加 css 类名，以便更好地扩展树表格样式 */
/* @var int $width 树表宽度 */
/* @var string|int $height 树表高度 */
/* @var int $maxHeight 树表最大高度(设置后树表height失效) */
/* @var array $treeTableHead 树表格头部 */
/* @var string $title 树表格标题 */
/* @var string $limits 每页数据条数选项 */
/* @var integer $limit 每页数据条数 */
/* @var string $skin 皮肤 */
/* @var string $size 尺寸 */
/* @var bool $even 开启间隔行样式 */
/* @var bool $ttColumnFilter 是否展示列筛选 */
/* @var bool $ttToolbarPrint 是否展示工具打印 */
/* @var bool $ttToolbarExports 是否展示工具导出 */
/* @var bool $ttToolbarRefresh 是否展示窗口刷新工具项 */
/* @var string $lineStyle 开启设置树表格多行样式 */
/* @var integer $cellMinWidth 设置所有普通单元格的最小宽度，一般用于列宽自动分配的情况。其优先级低于表头属性中的 minWidth */
/* @var integer $cellMaxWidth 设置所有普通单元格的最大宽度。其优先级低于表头属性中的 maxWidth */
/* @var boolean $openTotalRow 是否开启行合计 */
/* @var array $ttRowOperation 行操作项 */
/* @var array $cellOperation 单元格操作项 */
/* @var array $ttToolbarCustom 自定义头部工具栏(分组) ['left' => [...], 'right' => [...]] */
/* @var array $ttToolbarCustomRaw 自定义头部工具栏 */
/* @var array $ttToolbarFilter 树表格筛选 */
/* @var boolean $autoRequest 是否自动发起数据请求 */
/* @var array $extraJs 额外的JS脚本 */
/* @var array $ttToolbarTabDefault 工具选项卡默认请求参数 */
?>
<script>
    -function (global, top) { "use strict";
        global.ym2App.controller("ym2.ctrl.<?= $id ?>", [
            "$scope",
            "$http",
            "$timeout",
            "ymSpinner",
            "layui",
            "ym2",
            "swal",
            "lodash",
            "$compile",
            function ($scope, $http, $timeout, ymSpinner, layui, ym2, swal, lodash, $compile) {
                /*** ======================================== 树表内容构建 ======================================== ***/
                var topToastr = top.toastr;
                var topLayer = top.layui.layer;
                var topJquery = top.jQuery;
                var treeTable = layui.treeTable;
                var dropdown = layui.dropdown;
                var fixedWhere = {};
                var fixedWhere_toolbar_tag = <?= !empty($ttToolbarTabDefault) ? Json::encode($ttToolbarTabDefault) : '{}' ?>;

                var cols = [
                    <?php foreach ($treeTableHead as $options): ?>
                    <?php switch ($options['field']): case '__checkbox': ?>

                    // 行多选框
                    {
                        type:"checkbox",
                        fixed:"left",
                        // 样式
                        style: "<?= $options['style'] ?>",
                    },
                    <?php break; case '__toolbar': ?>

                    // 行工具栏
                    {
                        //标题
                        title: "<?= $options['title'] ?>",
                        <?php if (!empty($options['fixed'])): ?>
                        //固定列
                        fixed: "<?= $options['fixed'] ?>",
                        <?php endif; ?>
                        <?php if (!empty($options['width'])): ?>

                        // 当前列宽度
                        width: <?= is_numeric($options['width']) ? $options['width'] : "'{$options['width']}'" ?>,
                        <?php endif; ?>

                        minWidth: "<?= $options['minWidth'] ?>",
                        <?php if ($options['maxWidth']): ?>

                        // 当前列的最大宽度
                        maxWidth: "<?= $options['maxWidth'] ?>",
                        <?php endif; ?>

                        align: "<?= $options['align'] ?>",
                        // 样式
                        style: "<?= $options['style'] ?>",
                        toolbar:"#ym2_tool_<?= $id ?>",
                    },
                    <?php break; default: ?>

                    // 模板 - 函数写法
                    {
                        <?php if (!empty($options['field'])): ?>

                        // 字段
                        field: "<?= $options['field'] ?>",
                        <?php endif; ?>

                        // 标题
                        title: "<?= $options['title'] ?>",
                        <?php if (!empty($options['field'])): ?>

                        // 模板
                        templet: function (col) {
                            return col["<?= $options['field'] ?>"];
                        },
                        <?php endif; ?>

                        // 编辑事件
                        <?php if (!empty($options['edit'])): ?>

                        edit: function (d) {
                            var ctrlField = "<?= $options['ctrlField'] ?>";
                            if(!ctrlField.length || d[ctrlField]){
                                return "<?= $options['edit'] ?>";
                            }
                        },
                        <?php endif; ?>

                        // 是否开启列的排序功能。
                        sort: <?= $options['sort'] ?>,
                        // 单元格排列方式。可选值有：left | center | right
                        align: "<?= $options['align'] ?>",
                        <?php if (!empty($options['width'])): ?>

                        // 当前列宽度
                        width: <?= is_numeric($options['width']) ? $options['width'] : "'{$options['width']}'" ?>,
                        <?php endif; ?>

                        // 最小宽度
                        minWidth: "<?= $options['minWidth'] ?>",
                        // 样式
                        style: "<?= $options['style'] ?>",
                        // 当前列的最大宽度
                        <?php if ($options['maxWidth']): ?>

                        maxWidth: "<?= $options['maxWidth'] ?>",
                        <?php endif; ?>

                        // 前端行合计
                        <?php if ($options['totalRow']): ?>

                        totalRow: true,
                        <?php endif; ?>

                    },
                    <?php endswitch; ?>
                    <?php endforeach; ?>

                ];
                var isEnsureFixbar = false;
                var treeAsyncOption;
                <?php if ($treeAsyncOption): ?>

                treeAsyncOption = <?= $treeAsyncOption ?>;
                <?php else: ?>

                treeAsyncOption = {
                    enable: false,
                };
                <?php endif; ?>

                var treeTableOptions = {
                    id: "<?= 'ym2_' . $id ?>",
                    elem: "#ym2_builder_<?= $id ?>",
                    url: "<?= $url ?>",
                    page: <?= $page ? 'true' : 'false' ?>,
                    height: "<?= $height ?>",
                    title: "<?= H5::encode($title) ?>",
                    limits: <?= $limits ?>,
                    limit: <?= $limit ?>,
                    skin: "<?= !empty($skin) ? $skin : "line" ?>",
                    size: "<?= !empty($size) ? $size : "md" ?>",
                    even: <?= !empty($even) ? 'true' : 'false' ?>,
                    tree: {
                        // 异步加载子节点
                        async: treeAsyncOption,
                        <?php if ($treeCustomNameOption): ?>

                        // 自定义属性名的集合
                        customName: <?= $treeCustomNameOption ?>,
                        <?php endif; ?>
                        <?php if ($treeViewOption): ?>

                        // 视图相关的属性集合
                        view: <?= $treeViewOption ?>,
                        <?php endif; ?>
                        <?php if ($treeDataOption): ?>

                        // 数据相关的属性集合
                        data: <?= $treeDataOption ?>,
                        <?php endif; ?>

                    },
                    cols: [
                        cols,
                    ],
                    response: {
                        statusCode: <?= App::params('http.res.success') ?>,
                    },
                    parseData: function(result){
                        return {
                            code: result.code,
                            msg: result.msg,
                            count: result.data.count,
                            data: result.data.list,
                            // 后端行合计
                            totalRow: result.data.totalRow,
                            // 额外数据
                            extraData: result.data.extraData,
                        };
                    },
                    before: function () {
                        //判断是否是切换页面,而非首次加载
                        if (this.elem.next().hasClass('layui-table-tree')) {
                            //切换页面,关闭全部节点(防止异步加载瞬间加载所有展开节点)
                            treeTable.expandAll(treeTableOptions.id, false);
                        }
                    },
                    done: function(res, curr, count){
                        //console.log(res); // 得到当前渲染的数据
                        //console.log(curr);  // 得到当前页码
                        //console.log(count); // 得到数据总量
                        if (res.extraData) {
                            $scope.$apply(function () {
                                $scope.__extraData = res.extraData;
                            });
                        }

                        // 动态编译html中angular脚本
                        var compileEle = this.elem.next().find(".layui-table-main");
                        //compileEle.html($compile(compileEle.html())($scope));
                        $compile(compileEle.contents())($scope);

                        // 置顶图标
                        if (!isEnsureFixbar) {
                            layui.util.fixbar({
                                target: this.elem.next().find(".layui-table-main"),
                            });

                            isEnsureFixbar = true;
                        }
                    },
                };

                // 树表格最大高度
                <?php if ($maxHeight): ?>

                treeTableOptions.maxHeight = <?= $maxHeight ?>;
                <?php endif; ?>

                // 头部左侧工具栏
                <?php if (!empty($ttToolbarCustom['left'])): ?>

                treeTableOptions.toolbar = "#ym2_toolbar_<?= $id ?>";
                <?php elseif(
                !empty($ttToolbarCustom['right'])  // 工具栏右侧自定义不为空
                || !empty($ttToolbarFilter) // 树表格筛选工具项存在
                || $ttColumnFilter  // 列筛选工具项存在
                || $ttToolbarExports  // 工具导出存在
                || $ttToolbarPrint  // 工具打印存在
                || $ttToolbarRefresh // 工具刷新存在
                ): ?>

                treeTableOptions.toolbar = true;
                <?php endif; ?>

                // 是否开启行合计
                <?php if ($openTotalRow): ?>

                treeTableOptions.totalRow = true;
                <?php endif; ?>

                // 给树表格主容器追加 css 类名，以便更好地扩展树表格样式
                <?php if ($className): ?>

                treeTableOptions.className = "<?= $className ?>";
                <?php endif; ?>

                // 设置所有普通单元格的最小宽度，一般用于列宽自动分配的情况。其优先级低于表头属性中的 minWidth
                <?php if($cellMinWidth): ?>

                treeTableOptions.cellMinWidth = <?= $cellMinWidth ?>;
                <?php endif; ?>

                // 设置所有普通单元格的最大宽度。其优先级低于表头属性中的 maxWidth
                <?php if($cellMaxWidth): ?>

                treeTableOptions.cellMaxWidth = <?= $cellMaxWidth ?>;
                <?php endif; ?>

                // 树表格多行样式, 如高度
                <?php if (!empty($lineStyle)): ?>

                treeTableOptions.lineStyle = "<?= $lineStyle ?>";
                <?php endif; ?>

                treeTableOptions.defaultToolbar = [];
                // 工具栏右侧自定义
                <?php if (!empty($ttToolbarCustom['right'])): ?>
                <?php foreach ($ttToolbarCustom['right'] as $item): ?>

                treeTableOptions.defaultToolbar.push({
                    title: "<?= $item['title'] ?>",
                    layEvent: "<?= $item['options']['__event_id'] ?>",
                    icon: "<?= !empty($item['icon']) ? $item['icon'] : 'bi bi-heart' ?>",
                });
                <?php endforeach; ?>
                <?php endif; ?>

                // 列筛选
                <?php if($ttColumnFilter): ?>

                treeTableOptions.defaultToolbar.push("filter");
                <?php endif; ?>

                // 工具导出
                <?php if($ttToolbarExports): ?>

                treeTableOptions.defaultToolbar.push("exports");
                <?php endif; ?>

                // 工具打印
                <?php if($ttToolbarPrint): ?>

                treeTableOptions.defaultToolbar.push("print");
                <?php endif; ?>

                // 树表格筛选项
                <?php if (!empty($ttToolbarFilter)): ?>

                treeTableOptions.defaultToolbar.push({
                    title:"<?= $ttToolbarFilter['title'] ?>",
                    layEvent: "__ym2_tree_table_event_filter",
                    icon: "<?= $ttToolbarFilter['icon'] ?>",
                });
                <?php endif; ?>

                // 工具窗口刷新
                <?php if($ttToolbarRefresh): ?>

                treeTableOptions.defaultToolbar.push({
                    title: "刷新窗口",
                    layEvent: "__ym2_tree_table_event_refresh",
                    icon: "bi bi-arrow-clockwise",
                });
                <?php endif; ?>

                // 树表格宽度
                var tableWidth = "<?= $width ?>";
                if (tableWidth) {
                    treeTableOptions.width = tableWidth;
                }

                // 树表格数据重载
                var historyWhere = {};
                function reloadTreeTable(where, initPage) {
                    initPage = initPage || false;
                    where = where || historyWhere || {};
                    historyWhere = where;
                    var options = {
                        where: Object.assign( {}, where, fixedWhere, fixedWhere_toolbar_tag ),
                        scrollPos: "fixed",
                    };

                    // 初始化页码
                    if (initPage && treeTableOptions.page) {
                        options.page = {
                            curr: 1,
                        };
                    }

                    treeTable.reloadData(treeTableOptions.id, options);
                }

                <?php if ($autoRequest): //是否自动加载数据 ?>

                // 树表格渲染
                treeTableOptions.where = Object.assign(treeTableOptions.where || {}, fixedWhere_toolbar_tag);
                treeTable.render(treeTableOptions);
                <?php else: ?>

                var treeTableInstance;
                global.ym2BehaviorReqExport["<?= $id ?>"] = function (where) {
                    fixedWhere = where || {};
                    if (treeTableInstance) {
                        // 树表格重载
                        Object.keys(fixedWhere).length && reloadTreeTable(undefined, true);
                    } else {
                        // 树表格渲染
                        var originWhere = treeTableOptions.where || {};
                        Object.assign(originWhere, fixedWhere, fixedWhere_toolbar_tag);
                        treeTableOptions.where = originWhere;
                        treeTableInstance = treeTable.render(treeTableOptions);
                    }
                };
                <?php endif; ?>

                /*** ======================================== 树表格行事件构建 ======================================== ***/
                // 单元格编辑后的事件
                <?php if (!empty($cellOperation['edit'])): ?>

                treeTable.on("edit(" + treeTableOptions.id + ")", function(obj){
                    var field = obj.field; // 得到修改的字段
                    var rowData = obj.data; // 得到所在行所有键值
                    var value = obj.value; // 得到修改后的值
                    //var col = obj.getCol(); // 得到当前列的表头配置属性 -- v2.8.0 新增
                    var params;
                    var route;

                    switch (field) {
                    <?php foreach ($cellOperation['edit'] as $item): ?>
                        case "<?= $item['field'] ?>":
                            params = ym2.fillParams(<?= Json::encode($item['params']) ?>, rowData);
                            route = "<?= $item['route'] ?>";
                            break;
                    <?php endforeach; ?>
                    }

                    if (!route || !params) {
                        global.console.warn('route: ' + route, 'params: ' + params);
                        ym2.swal.fail(swal, "单元格编辑[route]或[params]参数缺失!");
                        return;
                    }

                    var url = ym2.addUrlQueryParam(route, params);
                    var bodyParam = {};
                    bodyParam[field] = value;
                    // show loading
                    var flag = ymSpinner.show();
                    $http.post(url, bodyParam).then(function (result) {
                        ymSpinner.hide(flag);

                        var data = result.data;
                        if (data.code === <?= App::params('http.res.success') ?>) {
                            // reload list
                            $timeout(function () {
                                reloadTreeTable();
                            }, 150);
                        } else if (data.code === <?= App::params('http.res.failure') ?>) {
                            ym2.swal.fail(swal, data.msg);
                        } else if (data.code === <?= App::params('http.res.unauthorized') ?>) {
                            // 授权失效, 去登录
                            ym2.swal.timer(
                                swal,
                                data.msg,
                                "自动跳转; <a href='<?= Url::to(App::params('admin.route.login'), '') ?>' target='_top'>立即跳转<a/>",
                                function () {
                                    top.open("<?= Url::to(App::params('admin.route.login'), '') ?>", "_self");
                                },
                                3000
                            );
                        } else {
                            ym2.swal.fail(swal, data.msg);
                        }
                    }, function (error) {
                        ymSpinner.hide(flag);
                        ym2.swal.fail(swal, error.data || "系统错误,发起请求失败!");
                        global.console.error(error);
                    });
                });
                <?php endif; ?>

                <?php if (!empty($ttRowOperation)): ?>

                // 行操作事件
                treeTable.on("tool(" + treeTableOptions.id + ")", function (obj) {
                    var event = obj.event;
                    var configs;
                    switch (event) {
                    <?php if (!empty($ttRowOperation['normal'])): ?>
                    <?php foreach ($ttRowOperation['normal'] as $item): ?>

                        case "<?= $item['options']['__event_id'] ?>":
                            configs = <?= Json::encode($item['options']) ?>;
                            rowEventCall("<?= $item['type'] ?>", configs, obj);
                            break;
                    <?php endforeach; ?>
                    <?php endif; ?>

                        case "ym2_row_event_group_more": // 分组更多
                        <?php if (!empty($ttRowOperation['more'])): ?>

                            // 行数据, 一维JSON
                            var rowData = obj.data || {};
                            // 动态添加操作
                            var dropdownTempData = [
                                <?php foreach ($ttRowOperation['more'] as $item): ?>

                                {
                                    title: "<?= $item['options']['title'] ?>",
                                    id: "<?= $item['options']['__event_id'] ?>",
                                    templet: function (d) {
                                        return '<i class="<?= $item["options"]["icon"] ?>"></i>&nbsp;' + d.title;
                                    },
                                    php_configs: <?= Json::encode($item['options']) ?>,
                                    php_type: "<?= $item['type'] ?>",
                                },
                                <?php endforeach; ?>

                            ];
                            var dropdownData = [];
                            dropdownTempData.forEach(function (value, index, array) {
                                var operationId = value.php_configs.operationId;
                                if (ym2.typeOf(operationId) !== 'string' || (operationId.length && rowData[operationId])) {
                                    dropdownData.push(value);
                                }
                            });

                            if (dropdownData.length) { // 存在下拉菜单配置项
                                dropdown.render({
                                    // 触发事件的 DOM 对象
                                    elem: this,
                                    trigger: "click",
                                    // 外部事件触发即显示
                                    show: true,
                                    data: dropdownData,
                                    click: function(data){
                                        rowEventCall(data.php_type, data.php_configs, obj);
                                    },
                                    align: "left", // 右对齐弹出
                                    style: "box-shadow: 1px 1px 10px rgb(0 0 0 / 12%);", // 设置额外样式
                                });
                            } else { // 暂无菜单提示
                                topToastr.info("暂无更多操作!");
                            }

                        <?php endif; ?>

                            break;
                    }

                });

                <?php endif; ?>

                /**
                 * 行操作 - 事件调用
                 * @param type 调用类型: modal, ajax, page
                 * @param configs 选项, 查看构建器$ttRowOperation
                 * @param obj 行对象
                 */
                function rowEventCall(type, configs, obj) {
                    switch (type) {
                        case 'modal':
                            rowModalCall(configs, obj);
                            break;
                        case 'ajax':
                            rowAjaxCall(configs, obj);
                            break;
                        case 'page':
                            rowPageCall(configs, obj);
                            break;
                    }
                }

                /**
                 * 行操作 - modal调用
                 * @param configs 选项, 查看构建器$ttRowOperation
                 * @param obj 行对象
                 */
                function rowModalCall(configs, obj) {
                    // 行数据, 一维JSON
                    var rowData = obj.data || {};
                    // title
                    var title = configs.title;
                    // URL参数
                    var params = ym2.fillParams(configs.params || [], rowData);
                    // URL
                    var url = configs.route;
                    // modal width
                    var width = configs.width;
                    // modal height
                    var height = configs.height;
                    // modal footer close btn
                    var footerCloseBtn = configs.closeBtn;
                    // layer screen obj
                    var layerScreenObj = ym2.layerScreenOptions(width);

                    // layer动态唯一索引
                    var activeIndex = topLayer.index;
                    // iframe 模态框
                    var layerCf = {
                        type: 2, // iframe
                        //skin: 'layui-layer-win10',
                        area: [layerScreenObj.width, height],
                        title: title,
                        shade: 0.3, // 遮罩透明度
                        shadeClose: false, // 点击遮罩区域，关闭弹层
                        //closeBtn: layerScreenObj.closeBtn,
                        maxmin: true, // 允许全屏最小化
                        anim: 0, // 0-6 的动画形式，-1 不开启
                        scrollbar: false, // 打开弹层时，是否允许浏览器出现滚动条。
                        content: ym2.addUrlQueryParam(url, params),
                        success: function(layero, index, that){
                            // 弹层的最外层元素的 jQuery 对象
                            //console.log(layero);
                            // 弹层的索引值
                            //console.log(index);
                            // 弹层内部原型链中的 this --- 2.8+
                            //console.log(that);
                            // 获取 iframe 的窗口对象, 添加来源追踪
                            var iframeWin = top[layero.find("iframe")[0]["name"]];
                            iframeWin.__REFERER_WIN_NAME = global.name;
                            //键盘事件关闭
                            topJquery(".ym2_kc_" + activeIndex).focus().on("keydown", function (e) {
                                // 空格和回车键
                                if (e.keyCode === 13 || e.keyCode === 32) {
                                    topJquery(this).trigger("click");
                                }
                            });
                        },
                    };

                    if (footerCloseBtn) {
                        layerCf.btn = ['<span class="ym2_keydown_close ym2_kc_' + activeIndex + '" tabindex="0">关闭</span>'];
                    }

                    topLayer.open(layerCf);
                }

                /**
                 * 行操作 - page调用
                 * @param configs 选项, 查看构建器$ttRowOperation
                 * @param obj 行对象
                 */
                function rowPageCall(configs, obj) {
                    // 行数据, 一维JSON
                    var rowData = obj.data || {};
                    // URL参数
                    var params = ym2.fillParams(configs.params || [], rowData);
                    // URL
                    var url = configs.route;
                    // target
                    var target = configs.target;
                    // href
                    var href = ym2.addUrlQueryParam(url, params);
                    // 打开
                    global.open(href, target);
                }

                /**
                 * 行操作 - ajax调用
                 * @param configs 选项, 查看构建器$ttRowOperation
                 * @param obj 行对象
                 */
                function rowAjaxCall(configs, obj) {
                    ym2.swal.question(swal, configs.questionTitle, configs.questionDescription, function (result) {
                        /* Read more about isConfirmed, isDenied below */
                        if (result.isConfirmed) {
                            // 发起ajax
                            rowAjaxRequest(configs, obj);
                        }
                    });
                }

                /**
                 * 行操作 - 发起ajax请求
                 * @param configs 选项, 查看构建器$ttRowOperation
                 * @param obj 行对象
                 */
                function rowAjaxRequest(configs, obj) {
                    // 行数据, 一维JSON
                    var rowData = obj.data || {};
                    // URL参数
                    var params = ym2.fillParams(configs.params || [], rowData);
                    // URL
                    var url = configs.route;
                    // HTTP method
                    var method = configs.method;

                    var instance;
                    if (method.toUpperCase() === "GET") {
                        var u = ym2.addUrlQueryParam(url, params);
                        instance = $http.get(u);
                    } else if (method.toUpperCase() === "POST") {
                        instance = $http.post(url, params);
                    }

                    // show loading
                    var flag = ymSpinner.show();
                    instance.then(function (result) {
                        ymSpinner.hide(flag);

                        var data = result.data;
                        if (data.code === <?= App::params('http.res.success') ?>) {
                            ym2.swal.ok(swal, data.msg);
                            // reload list
                            $timeout(function () {
                                reloadTreeTable();
                            }, 150);
                        } else if (data.code === <?= App::params('http.res.failure') ?>) {
                            ym2.swal.fail(swal, data.msg);
                        } else if (data.code === <?= App::params('http.res.unauthorized') ?>) {
                            // 授权失效, 去登录
                            ym2.swal.timer(
                                swal,
                                data.msg,
                                "自动跳转; <a href='<?= Url::to(App::params('admin.route.login'), '') ?>' target='_top'>立即跳转<a/>",
                                function () {
                                    top.open("<?= Url::to(App::params('admin.route.login'), '') ?>", "_self");
                                },
                                3000
                            );
                        } else {
                            ym2.swal.fail(swal, data.msg);
                        }
                    }, function (error) {
                        ymSpinner.hide(flag);
                        ym2.swal.fail(swal, error.data || "系统错误,发起请求失败!");
                        global.console.error(error);
                    });

                }

                /*** ======================================== 树表格工具事件构建 ======================================== ***/
                // 头部工具栏事件
                treeTable.on("toolbar(" + treeTableOptions.id + ")", function (obj) {
                    var configs;
                    switch (obj.event) {
                        // 页面刷新
                        case "__ym2_tree_table_event_refresh":
                            refreshCurrentPage();
                            break;
                        // 树表格筛选
                        case "__ym2_tree_table_event_filter":
                            treeTableFilterToggle();
                            break;
                        <?php foreach ($ttToolbarCustomRaw as $item): ?>

                        case "<?= $item['options']['__event_id'] ?>":
                            configs = <?= Json::encode($item) ?>;
                            headToolbarEventDispatch(configs, obj);
                            break;
                        <?php endforeach; ?>

                    }
                });

                /**
                 * 头部工具栏事件 - 类型分发
                 * @param configs 工具项配置
                 * @param obj 树表格对象
                 */
                function headToolbarEventDispatch(configs, obj) {
                    switch (configs.options.type) {
                        case "page": // 单页
                            headToolbarPageEvent(configs, obj);
                            break;
                        case "modal": // 模态框
                            headToolbarModalEvent(configs, obj);
                            break;
                        case "ajax": // AJAX
                            headToolbarAjaxEvent(configs, obj);
                            break;
                        case "other"://其他
                            headToolbarOtherEvent(configs, obj);
                            break;
                    }
                }

                /**
                 * 头部工具栏事件 - 其他调用
                 * @param configs 工具项配置
                 * @param obj 树表格对象
                 */
                function headToolbarOtherEvent(configs, obj) {
                    switch (configs.options.__event_id) {
                        case "__ym2_tree_table_expand_all_true"://展开
                            treeTable.expandAll(treeTableOptions.id, true);
                            break;
                        case "__ym2_tree_table_expand_all_false"://折叠
                            treeTable.expandAll(treeTableOptions.id, false);
                            break;
                    }
                }

                /**
                 * 树表格筛选表单切换
                 */
                var dynamicField = "ym2TreeTableFilterShow_<?= $id ?>";
                var ym2TreeTableStorage = layui.data('ym2_tree_table');
                $scope[dynamicField] = ym2TreeTableStorage[dynamicField] !== "hide";
                function treeTableFilterToggle() {
                    $scope.$apply(function () {
                        var isShowFilter = $scope[dynamicField];
                        $scope[dynamicField] = !isShowFilter;
                        layui.data("ym2_tree_table", {
                            key: dynamicField,
                            value: !isShowFilter ? "show" : "hide",
                        });
                    });
                }

                /**
                 * 头部工具栏事件 - 刷新
                 */
                function refreshCurrentPage() {
                    global.location.reload(true);
                }

                /**
                 * 头部工具栏事件 - 单页
                 * @param configs 工具项配置
                 * @param obj 树表格对象
                 */
                function headToolbarPageEvent(configs, obj) {
                    // Request Params
                    var requestParams = configs.options.params || [];
                    // URL
                    var url = configs.options.route;
                    // target
                    var target = configs.options.target;
                    // 是否必须选择checkbox
                    var mustSelectCheckbox = !!configs.options.__mustSelectCheckbox;
                    // 处理后的请求参数
                    var params;

                    // 请参数不为空
                    if (ym2.keys(requestParams).length) {
                        if (mustSelectCheckbox) {
                            // 选中的数据, 多维JSON
                            var data = treeTable.checkStatus(treeTableOptions.id).data;
                            if (!data.length) {
                                topToastr.warning("请选择数据列!");
                                return;
                            }

                            // URL参数
                            params = ym2.fillParamsMany(requestParams || [], data);
                        } else {
                            params = requestParams;
                        }

                        // href
                        url = ym2.addUrlQueryParam(url, params);
                    }

                    // 打开
                    global.open(url, target);
                }

                /**
                 * 头部工具栏事件 - 模态框
                 * @param configs 工具项配置
                 * @param obj 树表格对象
                 */
                function headToolbarModalEvent(configs, obj) {
                    // Request Params
                    var requestParams = configs.options.params || [];
                    // URL
                    var url = configs.options.route;
                    // modal width
                    var width = configs.options.width;
                    // modal height
                    var height = configs.options.height;
                    // modal footer close btn
                    var footerCloseBtn = configs.options.closeBtn;
                    // layer screen obj
                    var layerScreenObj = ym2.layerScreenOptions(width);
                    // 是否必须选择checkbox
                    var mustSelectCheckbox = !!configs.options.__mustSelectCheckbox;
                    // 处理后的请求参数
                    var params;

                    // 请参数不为空
                    if (ym2.keys(requestParams).length) {
                        if (mustSelectCheckbox) {
                            // 选中的数据, 多维JSON
                            var data = treeTable.checkStatus(treeTableOptions.id).data;
                            if (!data.length) {
                                topToastr.warning("请选择数据列!");
                                return;
                            }

                            // URL参数
                            params = ym2.fillParamsMany(requestParams || [], data);
                        } else {
                            params = requestParams;
                        }

                        // href
                        url = ym2.addUrlQueryParam(url, params);
                    }

                    // layer动态唯一索引
                    var activeIndex = topLayer.index;
                    // iframe 模态框
                    var layerCf = {
                        type: 2, // iframe
                        //skin: 'layui-layer-win10',
                        area: [layerScreenObj.width, height],
                        title: configs.title,
                        shade: 0.3, // 遮罩透明度
                        shadeClose: false, // 点击遮罩区域，关闭弹层
                        //closeBtn: layerScreenObj.closeBtn,
                        maxmin: true, // 允许全屏最小化
                        anim: 0, // 0-6 的动画形式，-1 不开启
                        scrollbar: false, // 打开弹层时，是否允许浏览器出现滚动条。
                        content: url,
                        success: function(layero, index, that){
                            // 弹层的最外层元素的 jQuery 对象
                            //console.log(layero);
                            // 弹层的索引值
                            //console.log(index);
                            // 弹层内部原型链中的 this --- 2.8+
                            //console.log(that);
                            // 获取iframe的窗口对象, 添加来源追踪
                            var iframeWin = top[layero.find("iframe")[0]["name"]];
                            iframeWin.__REFERER_WIN_NAME = global.name;
                            // 键盘事件关闭
                            topJquery(".ym2_kc_" + activeIndex).focus().on("keydown", function (e) {
                                // 空格和回车键
                                if (e.keyCode === 13 || e.keyCode === 32) {
                                    topJquery(this).trigger("click");
                                }
                            });
                        },
                    };
                    if (footerCloseBtn) {
                        layerCf.btn = ['<span class="ym2_keydown_close ym2_kc_' + activeIndex + '" tabindex="0">关闭</span>'];
                    }

                    topLayer.open(layerCf);
                }

                /**
                 * 头部工具栏事件 - AJAX
                 * @param configs 工具项配置
                 * @param obj 树表格对象
                 */
                function headToolbarAjaxEvent(configs, obj) {
                    // Request Params
                    var requestParams = configs.options.params || [];
                    // URL参数
                    var params = {};
                    // 是否必须选择checkbox
                    var mustSelectCheckbox = !!configs.options.__mustSelectCheckbox;

                    // 请参数不为空
                    if (ym2.keys(requestParams).length) {
                        if (mustSelectCheckbox) {
                            // 选中的数据, 多维JSON
                            var data = treeTable.checkStatus(treeTableOptions.id).data;
                            if (!data.length) {
                                topToastr.warning("请选择数据列!");
                                return;
                            }

                            // URL参数
                            params = ym2.fillParamsMany(requestParams || [], data);
                        } else {
                            params = requestParams;
                        }
                    }

                    ym2.swal.question(swal, configs.options.questionTitle, configs.options.questionDescription, function (result) {
                        /* Read more about isConfirmed, isDenied below */
                        if (result.isConfirmed) {
                            // 发起ajax
                            headToolbarAjaxRequest(configs, params, obj);
                        }
                    });
                }

                /**
                 * 头部工具栏AJAX请求
                 * @param configs 工具项配置
                 * @param params 请求参数
                 * @param obj 树表格对象
                 */
                function headToolbarAjaxRequest(configs, params, obj) {
                    // URL
                    var url = configs.options.route;
                    // HTTP method
                    var method = configs.options.method;

                    var instance;
                    if (method.toUpperCase() === "GET") {
                        var u = ym2.addUrlQueryParam(url, params);
                        instance = $http.get(u);
                    } else if (method.toUpperCase() === "POST") {
                        instance = $http.post(url, params);
                    }

                    // show loading
                    var flag = ymSpinner.show();
                    instance.then(function (result) {
                        ymSpinner.hide(flag);

                        var data = result.data;
                        if (data.code === <?= App::params('http.res.success') ?>) {
                            ym2.swal.ok(swal, data.msg);
                            // reload list
                            $timeout(function () {
                                reloadTreeTable();
                            }, 150);
                        } else if (data.code === <?= App::params('http.res.failure') ?>) {
                            ym2.swal.fail(swal, data.msg);
                        } else if (data.code === <?= App::params('http.res.unauthorized') ?>) {
                            // 授权失效, 去登录
                            ym2.swal.timer(
                                swal,
                                data.msg,
                                "自动跳转; <a href='<?= Url::to(App::params('admin.route.login'), '') ?>' target='_top'>立即跳转<a/>",
                                function () {
                                    top.open("<?= Url::to(App::params('admin.route.login'), '') ?>", "_self");
                                },
                                3000
                            );
                        } else {
                            ym2.swal.fail(swal, data.msg);
                        }
                    }, function (error) {
                        ymSpinner.hide(flag);
                        ym2.swal.fail(swal, error.data || "系统错误, 发起请求失败!");
                        global.console.error(error);
                    });

                }

                /*** ======================================== 树表格筛选 ======================================== ***/
                // 初始化筛选项
                $scope.ym2FilterForm = {};
                $scope.initFilterForm = function () {
                    <?php if (!empty($ttToolbarFilter)): ?>

                    var selectLinkDefaultValue;
                    <?php foreach ($ttToolbarFilter['columns'] as $field => $columns): ?>
                    <?php switch ($columns['control']): case 'datetime':?>
                    <?php case 'date': ?>
                    <?php case 'year': ?>
                    <?php case 'month': ?>
                    <?php case 'time': ?>
                    <?php case 'number': ?>
                    <?php case 'text': ?>
                    <?php case 'select': ?>

                    $scope.ym2FilterForm["<?= $field ?>"] = "<?= $columns['default'] ?>";
                    <?php break; case 'select_link': //多级下拉联动 ?>

                    selectLinkDefaultValue = "<?= $columns['default'] ?>";
                    if (selectLinkDefaultValue) {
                        selectLinkDefaultValue = lodash.trim(selectLinkDefaultValue);
                    }

                    $scope.ym2FilterForm["<?= $field ?>"] = selectLinkDefaultValue;
                    // 触发change
                    if (selectLinkDefaultValue) {
                        $scope.selectLinkRequest("<?= $field ?>", "<?= $columns['targetLink'] ?>", "<?= $columns['route'] ?>")
                    }

                    <?php break;endswitch; ?>
                    <?php endforeach; ?>
                    <?php endif; ?>

                };

                // 多级下拉联动 - 发起请求
                $scope.selectLinkRequest = function (currentField, targetField, url) {
                    var queryParams = {};
                    var currentValue = $scope.ym2FilterForm[currentField];

                    // 空值处理
                    if (!currentValue || !lodash.trim(currentValue)) {
                        // 初始化目标连接的值
                        $scope.ym2FilterForm[targetField] = " ";
                        // 初始化目标连接选项
                        $scope[targetField + '__options'] = [];
                        return;
                    }

                    queryParams[currentField] = currentValue;
                    // show loading
                    var flag = ymSpinner.show();
                    $http.get(ym2.addUrlQueryParam(url, queryParams)).then(function (result) {
                        ymSpinner.hide(flag);

                        var data = result.data;
                        if (data.code === <?= App::params('http.res.success') ?>) {
                            // 初始化目标连接的值
                            $scope.ym2FilterForm[targetField] = " ";
                            // 设置目标连接选项
                            $scope[targetField + '__options'] = data.data || [];
                        } else if (data.code === <?= App::params('http.res.failure') ?>) {
                            topToastr.error(data.msg);
                        } else if (data.code === <?= App::params('http.res.unauthorized') ?>) {
                            // 授权失效, 去登录
                            ym2.swal.timer(
                                swal,
                                data.msg,
                                "自动跳转; <a href='<?= Url::to(App::params('admin.route.login'), '') ?>' target='_top'>立即跳转<a/>",
                                function () {
                                    top.open("<?= Url::to(App::params('admin.route.login'), '') ?>", "_self");
                                },
                                3000
                            );
                        } else {
                            topToastr.error(data.msg);
                        }

                    }, function (error) {
                        ymSpinner.hide(flag);
                        topToastr.error(error.data || "系统错误, 发起请求失败!");
                        global.console.error(error);
                    });
                };

                // 重置筛选项
                $scope.resetFilter = function () {
                    $scope.initFilterForm();
                    // 重载树表格
                    reloadTreeTable($scope.ym2FilterForm, true);
                };

                /**
                 * 提交筛选
                 */
                $scope.submitFilter = function () {
                    // 重载树表格
                    reloadTreeTable($scope.ym2FilterForm, true);
                };
                // 设置工具选项卡筛选
                $scope.triggerTab = function (where) {
                    fixedWhere_toolbar_tag = where;
                    reloadTreeTable(undefined, true);
                };
                //额外的JS脚本
                <?= !empty($extraJs) ? implode("\n", $extraJs) : '' ?>

                // 初始化筛选表单
                $scope.initFilterForm();

                //暴露给window,用于刷新回调
                global.ym2CbkExport["<?= $id ?>"] = reloadTreeTable;

            }]);

    }(window, top);
</script>
